home *** CD-ROM | disk | FTP | other *** search
/ Skunkware 5 / Skunkware 5.iso / src / X11 / xpaint-2.1.1 / circleOp.c < prev    next >
C/C++ Source or Header  |  1995-05-03  |  8KB  |  262 lines

  1. /* +-------------------------------------------------------------------+ */
  2. /* | Copyright 1992, 1993, David Koblas (koblas@netcom.com)            | */
  3. /* |                                                                   | */
  4. /* | Permission to use, copy, modify, and to distribute this software  | */
  5. /* | and its documentation for any purpose is hereby granted without   | */
  6. /* | fee, provided that the above copyright notice appear in all       | */
  7. /* | copies and that both that copyright notice and this permission    | */
  8. /* | notice appear in supporting documentation.  There is no           | */
  9. /* | representations about the suitability of this software for        | */
  10. /* | any purpose.  this software is provided "as is" without express   | */
  11. /* | or implied warranty.                                              | */
  12. /* |                                                                   | */
  13. /* +-------------------------------------------------------------------+ */
  14.  
  15. #include <X11/Intrinsic.h>
  16. #include <X11/StringDefs.h>
  17. #include <math.h>
  18. #include "xpaint.h"
  19. #include "misc.h"
  20. #include "Paint.h"
  21.  
  22. #define    FILL        0x02
  23. #define CIRCLE        0x01
  24. #define    ISFILL(x)    ((x) & FILL)
  25. #define ISCIRCLE(x)    ((x) & CIRCLE)
  26.  
  27. typedef struct {
  28.     Boolean    typeFlag, swap;
  29.     int    rx, ry, startX, startY, endX, endY, drawn, flag;
  30.     GC    gcx;
  31. } LocalInfo;
  32.  
  33. static int radiusMode = False;
  34.  
  35. static XRectangle *draw(Widget w, Drawable d, GC lgc, GC fgc, LocalInfo *l)
  36. {
  37.     static XRectangle    rect;
  38.     XArc        arc;
  39.     int        sx = l->startX, sy = l->startY;
  40.     int        ex = l->endX, ey = l->endY;
  41.  
  42.     if (l->startX == l->endX && l->startY == l->endY)
  43.         return NULL;
  44.  
  45.     arc.x      = MIN(sx, ex);
  46.     arc.y      = MIN(sy, ey);
  47.     arc.width  = MAX(sx, ex) - arc.x;
  48.     arc.height = MAX(sy, ey) - arc.y;
  49.  
  50.     if (radiusMode) {
  51.         int    r2 = arc.width * arc.width + arc.height * arc.height;
  52.         int    r;
  53.         
  54.         r = sqrt((double)r2);
  55.         arc.x = l->startX - r;
  56.         arc.y = l->startY - r;
  57.         arc.width  = r * 2;
  58.         arc.height = r * 2;
  59.     } else {
  60.         if (ISCIRCLE(l->typeFlag))
  61.             arc.height = arc.width = MAX(arc.width, arc.height);
  62.         if (arc.x != sx)
  63.             arc.x = sx - arc.width;
  64.         if (arc.y != sy)
  65.             arc.y = sy - arc.height;
  66.     }
  67.     arc.angle1 = 0;
  68.     arc.angle2 = 360*64;
  69.  
  70.     if (fgc != None)
  71.         XFillArcs(XtDisplay(w), d, fgc, &arc, 1);
  72.     if (lgc != None)
  73.         XDrawArcs(XtDisplay(w), d, lgc, &arc, 1);
  74.  
  75.     rect.x = arc.x;
  76.     rect.y = arc.y;
  77.     rect.width = arc.width + 1;
  78.     rect.height = arc.height + 1;
  79.  
  80.     return ▭
  81. }
  82.  
  83. static void    press(Widget w, LocalInfo *l, 
  84.             XButtonEvent *event, OpInfo *info) 
  85. {
  86.     /*
  87.     **  Check to make sure all buttons are up, before doing this
  88.     */
  89.     if ((event->state & (Button1Mask|Button2Mask|Button3Mask|Button4Mask|Button5Mask)) != 0)
  90.         return;
  91.  
  92.     l->rx   = info->x;
  93.     l->ry   = info->y;
  94.     l->endX = l->startX = event->x;
  95.     l->endY = l->startY = event->y;
  96.  
  97.     l->swap = (event->button == Button2);
  98.  
  99.     l->typeFlag = (event->state & ShiftMask) ? CIRCLE : 0;
  100.  
  101.     l->drawn = False;
  102. }
  103.  
  104. static void    motion(Widget w, LocalInfo *l, 
  105.             XMotionEvent *event, OpInfo *info) 
  106. {
  107.     if (l->drawn) 
  108.         draw(w, info->drawable, l->gcx, None, l);
  109.  
  110.     l->endX = event->x;
  111.     l->endY = event->y;
  112.  
  113.     /*
  114.     **  Really set this flag in the if statement
  115.     */
  116.     l->typeFlag = (event->state & ShiftMask) ? CIRCLE : 0;
  117.     l->drawn = (draw(w, info->drawable, l->gcx, None, l) != NULL);
  118. }
  119.  
  120. static void    release(Widget w, LocalInfo *l, 
  121.             XButtonEvent *event, OpInfo *info) 
  122. {
  123.     XRectangle    *undo;
  124.     int        mask;
  125.     GC        fgc, lgc;
  126.  
  127.     /*
  128.     **  Check to make sure all buttons are up, before doing this
  129.     */
  130.     mask = Button1Mask|Button2Mask|Button3Mask|Button4Mask|Button5Mask;
  131.     switch (event->button) {
  132.     case Button1:    mask ^= Button1Mask; break;
  133.     case Button2:    mask ^= Button2Mask; break;
  134.     case Button3:    mask ^= Button3Mask; break;
  135.     case Button4:    mask ^= Button4Mask; break;
  136.     case Button5:    mask ^= Button5Mask; break;
  137.     }
  138.     if ((event->state & mask) != 0)
  139.         return;
  140.  
  141.     if (l->drawn && info->surface == opWindow) 
  142.         draw(w, info->drawable, l->gcx, None, l);
  143.  
  144.     if (info->surface == opWindow && info->isFat)
  145.         return;
  146.  
  147.     UndoStart(w, info);
  148.  
  149.     l->startX = l->rx;
  150.     l->startY = l->ry;
  151.     l->endX = event->x;
  152.     l->endY = event->y;
  153.  
  154.     if (l->swap) {
  155.         fgc = info->first_gc;
  156.         lgc = info->second_gc;
  157.     } else {
  158.         fgc = info->second_gc;
  159.         lgc = info->first_gc;
  160.     }
  161.  
  162.     if (!ISFILL(l->flag))
  163.         fgc = None;
  164.  
  165.     undo = draw(w, info->drawable, lgc, fgc, l);
  166.  
  167.     if (info->surface == opPixmap && undo != NULL) {
  168.         UndoSetRectangle(w, undo);
  169.         PwUpdate(w, undo, False);
  170.     }
  171. }
  172.  
  173. /*
  174. **  Those public functions
  175. */
  176. void *CircleAdd(Widget w)
  177. {
  178.     LocalInfo    *l = (LocalInfo*)XtMalloc(sizeof(LocalInfo));
  179.     l->flag = CIRCLE;
  180.     l->gcx  = GetGCX(w);
  181.         XtVaSetValues(w, XtNcompress, True, NULL);
  182.     OpAddEventHandler(w, opWindow, ButtonPressMask, FALSE, (OpEventProc)press, l);
  183.     OpAddEventHandler(w, opWindow, ButtonMotionMask, FALSE, (OpEventProc)motion, l);
  184.     OpAddEventHandler(w, opWindow|opPixmap, ButtonReleaseMask, FALSE, (OpEventProc)release, l);
  185.     SetCrossHairCursor(w);
  186.     return l;
  187. }
  188. void CircleRemove(Widget w, LocalInfo *l)
  189. {
  190.     OpRemoveEventHandler(w, opWindow, ButtonPressMask, FALSE, (OpEventProc)press, l);
  191.     OpRemoveEventHandler(w, opWindow, ButtonMotionMask, FALSE, (OpEventProc)motion, l);
  192.     OpRemoveEventHandler(w, opWindow|opPixmap, ButtonReleaseMask, FALSE, (OpEventProc)release, l);
  193.     XtFree((XtPointer)l);
  194. }
  195. void *FCircleAdd(Widget w)
  196. {
  197.     LocalInfo    *l = (LocalInfo*)XtMalloc(sizeof(LocalInfo));
  198.     l->flag = CIRCLE|FILL;
  199.     l->gcx  = GetGCX(w);
  200.         XtVaSetValues(w, XtNcompress, True, NULL);
  201.     OpAddEventHandler(w, opWindow, ButtonPressMask, FALSE, (OpEventProc)press, l);
  202.     OpAddEventHandler(w, opWindow, ButtonMotionMask, FALSE, (OpEventProc)motion, l);
  203.     OpAddEventHandler(w, opWindow|opPixmap, ButtonReleaseMask, FALSE, (OpEventProc)release, l);
  204.     SetCrossHairCursor(w);
  205.     return l;
  206. }
  207. void FCircleRemove(Widget w, LocalInfo *l)
  208. {
  209.     OpRemoveEventHandler(w, opWindow, ButtonPressMask, FALSE, (OpEventProc)press, l);
  210.     OpRemoveEventHandler(w, opWindow, ButtonMotionMask, FALSE, (OpEventProc)motion, l);
  211.     OpRemoveEventHandler(w, opWindow|opPixmap, ButtonReleaseMask, FALSE, (OpEventProc)release, l);
  212.     XtFree((XtPointer)l);
  213. }
  214. void *OvalAdd(Widget w)
  215. {
  216.     LocalInfo    *l = (LocalInfo*)XtMalloc(sizeof(LocalInfo));
  217.     l->flag = 0;
  218.     l->gcx  = GetGCX(w);
  219.         XtVaSetValues(w, XtNcompress, True, NULL);
  220.     OpAddEventHandler(w, opWindow, ButtonPressMask, FALSE, (OpEventProc)press, l);
  221.     OpAddEventHandler(w, opWindow, ButtonMotionMask, FALSE, (OpEventProc)motion, l);
  222.     OpAddEventHandler(w, opWindow|opPixmap, ButtonReleaseMask, FALSE, (OpEventProc)release, l);
  223.     SetCrossHairCursor(w);
  224.     return l;
  225. }
  226. void OvalRemove(Widget w, LocalInfo *l)
  227. {
  228.     OpRemoveEventHandler(w, opWindow, ButtonPressMask, FALSE, (OpEventProc)press, l);
  229.     OpRemoveEventHandler(w, opWindow, ButtonMotionMask, FALSE, (OpEventProc)motion, l);
  230.     OpRemoveEventHandler(w, opWindow|opPixmap, ButtonReleaseMask, FALSE, (OpEventProc)release, l);
  231.     XtFree((XtPointer)l);
  232. }
  233. void *FOvalAdd(Widget w)
  234. {
  235.     LocalInfo    *l = (LocalInfo*)XtMalloc(sizeof(LocalInfo));
  236.     l->flag = FILL;
  237.     l->gcx  = GetGCX(w);
  238.         XtVaSetValues(w, XtNcompress, True, NULL);
  239.  
  240.     OpAddEventHandler(w, opWindow, ButtonPressMask, FALSE, (OpEventProc)press, l);
  241.     OpAddEventHandler(w, opWindow, ButtonMotionMask, FALSE, (OpEventProc)motion, l);
  242.     OpAddEventHandler(w, opWindow|opPixmap, ButtonReleaseMask, FALSE, (OpEventProc)release, l);
  243.     SetCrossHairCursor(w);
  244.     return l;
  245. }
  246. void FOvalRemove(Widget w, LocalInfo *l)
  247. {
  248.     OpRemoveEventHandler(w, opWindow, ButtonPressMask, FALSE, (OpEventProc)press, l);
  249.     OpRemoveEventHandler(w, opWindow, ButtonMotionMask, FALSE, (OpEventProc)motion, l);
  250.     OpRemoveEventHandler(w, opWindow|opPixmap, ButtonReleaseMask, FALSE, (OpEventProc)release, l);
  251.     XtFree((XtPointer)l);
  252. }
  253.  
  254. void CircleSetStyle(Boolean value)
  255. {
  256.     radiusMode = value;
  257. }
  258. Boolean CircleGetStyle()
  259. {
  260.     return radiusMode;
  261. }
  262.